/*******************************************************************************
* @copyright: Shenzhen Hangshun Chip Technology R&D Co., Ltd
* @filename:  hk32c030xx_flash.h
* @brief:     This file contains all the functions prototypes for the FLASH firmware
*             library.
* @author:    AE Team
*******************************************************************************/


/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __HK32C030XX_FLASH_H
#define __HK32C030XX_FLASH_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "hk32c030xx.h"

/** @addtogroup FLASH
  * @{
  */

/** @defgroup FLASH_Private_Defines FLASH_Private_Defines
* @{
*/
#define OB_BASE             ((uint32_t)0x1FFFF800U)       /*!< FLASH Option Bytes base address */
#define OB                  ((OB_TypeDef *) OB_BASE)

#define UID_BASE            ((uint32_t)0x1FFFF9B8U)       /* UID base address */

#define FLASH_KEY1  ((uint32_t)(0x45670123U ))
#define FLASH_KEY2  ((uint32_t)(0xCDEF89ABU ))

#define FLASH_OPTKEY1  ((uint32_t)(0x45670123U ))
#define FLASH_OPTKEY2  ((uint32_t)(0xCDEF89ABU ))

/******************  Bit definition for OB_RDP register  **********************/
#define OB_RDP_RDP_Pos       (0U)
#define OB_RDP_RDP_Msk       (0xFFU << OB_RDP_RDP_Pos)                         /*!< 0x000000FF */
#define OB_RDP_RDP           OB_RDP_RDP_Msk                                    /*!< Read protection option byte */
#define OB_RDP_nRDP_Pos      (8U)
#define OB_RDP_nRDP_Msk      (0xFFU << OB_RDP_nRDP_Pos)                        /*!< 0x0000FF00 */
#define OB_RDP_nRDP          OB_RDP_nRDP_Msk                                   /*!< Read protection complemented option byte */

/******************  Bit definition for OB_USER register  *********************/
#define OB_USER_USER_Pos     (16U)
#define OB_USER_USER_Msk     (0xFFU << OB_USER_USER_Pos)                       /*!< 0x00FF0000 */
#define OB_USER_USER         OB_USER_USER_Msk                                  /*!< User option byte */
#define OB_USER_nUSER_Pos    (24U)
#define OB_USER_nUSER_Msk    (0xFFU << OB_USER_nUSER_Pos)                      /*!< 0xFF000000 */
#define OB_USER_nUSER        OB_USER_nUSER_Msk                                 /*!< User complemented option byte */

/******************  Bit definition for OB_WRP0 register  *********************/
#define OB_WRP0_WRP0_Pos     (0U)
#define OB_WRP0_WRP0_Msk     (0xFFU << OB_WRP0_WRP0_Pos)                       /*!< 0x000000FF */
#define OB_WRP0_WRP0         OB_WRP0_WRP0_Msk                                  /*!< Flash memory write protection option bytes */
#define OB_WRP0_nWRP0_Pos    (8U)
#define OB_WRP0_nWRP0_Msk    (0xFFU << OB_WRP0_nWRP0_Pos)                      /*!< 0x0000FF00 */
#define OB_WRP0_nWRP0        OB_WRP0_nWRP0_Msk                                 /*!< Flash memory write protection complemented option bytes */

/**
  * @}
  */



/** @defgroup FLASH_Exported_Types FLASH_Exported_Types
  * @{
  */

/**
  * @brief  FLASH Status
  */
typedef enum
{
    FLASH_BUSY = 1,
    FLASH_ERROR_WRP,
    FLASH_ERROR_PROGRAM,
    FLASH_COMPLETE,
    FLASH_TIMEOUT
} FLASH_Status;

/**
  * @brief  FLASH_OB Status
  */
typedef struct
{
    __IO uint32_t USER_RDP;          /*!< FLASH option byte Read protection and user option,             Address offset: 0x00 */
    __IO uint32_t DATA;        /*!< User data byte 0 and 1 (stored in FLASH_OBR[23:16]), Address offset: 0x04 */
    __IO uint32_t WRP01;         /*!< FLASH option byte write protection 0 and 1,          Address offset: 0x08 */
    __IO uint32_t WRP23;         /*!< FLASH option byte write protection 2 and 3,          Address offset: 0x0C */
} OB_TypeDef;

/**
  * @}
  */

/** @defgroup FLASH_Exported_Constants FLASH_Exported_Constants
  * @{
  */

/** @defgroup FLASH_Latency FLASH_Latency
  * @{
  */
#define FLASH_Latency_0                ((uint32_t)0x00000000)  /*!< FLASH Zero Latency cycle */
#define FLASH_Latency_1                ((uint32_t)0x00000001)      /*!< FLASH One Latency cycle */
#define FLASH_Latency_2                ((uint32_t)0x00000002)  /*!< FLASH Zero Latency cycle */
#define FLASH_Latency_3                ((uint32_t)0x00000003)       /*!< FLASH One Latency cycle */
#define FLASH_Latency_7                ((uint32_t)0x00000004)  /*!< FLASH Zero Latency cycle */
#define FLASH_Latency_9                ((uint32_t)0x00000005)       /*!< FLASH One Latency cycle */
#define FLASH_Latency_19               ((uint32_t)0x00000006)       /*!< FLASH One Latency cycle */
#define FLASH_Latency_39               ((uint32_t)0x00000007)       /*!< FLASH One Latency cycle */
#define IS_FLASH_LATENCY(LATENCY) (((LATENCY) == FLASH_Latency_0) || \
                                   ((LATENCY) == FLASH_Latency_1) || \
                                   ((LATENCY) == FLASH_Latency_2) || \
                                   ((LATENCY) == FLASH_Latency_3) || \
                                   ((LATENCY) == FLASH_Latency_7) || \
                                   ((LATENCY) == FLASH_Latency_9) || \
                                   ((LATENCY) == FLASH_Latency_19) || \
                                   ((LATENCY) == FLASH_Latency_39))
/**
  * @}
  */

/** @defgroup FLASH_Interrupts FLASH_Interrupts
  * @{
  */

#define FLASH_IT_EOP                   FLASH_CR_EOPIE  /*!< End of programming interrupt source */
#define FLASH_IT_ERR                   FLASH_CR_ERRIE  /*!< Error interrupt source */
#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFFFFEBFF) == 0x00000000) && (((IT) != 0x00000000)))
/**
  * @}
  */

/** @defgroup FLASH_Address FLASH_Address
  * @{
  */
#define IS_FLASH_PROGRAM_ADDRESS(ADDRESS) (((ADDRESS) >= 0x08000000) && ((ADDRESS) <= 0x0800FFFF))

/**
  * @}
  */

/** @defgroup FLASH_OB_DATA_ADDRESS FLASH_OB_DATA_ADDRESS
  * @{
  */
#define IS_OB_DATA_ADDRESS(ADDRESS) (((ADDRESS) == 0x1FFFF804) || ((ADDRESS) == 0x1FFFF840))
/**
  * @}
  */



/** @defgroup FLASH_Option_Bytes_Write_Protection FLASH_Option_Bytes_Write_Protection
  * @{
  */

#define OB_WRP_Sector0              ((uint32_t)0x00000001) /* Write protection of Sector */
#define OB_WRP_Sector1              ((uint32_t)0x00000002) /* Write protection of Sector */
#define OB_WRP_Sector2              ((uint32_t)0x00000004) /* Write protection of Sector */
#define OB_WRP_Sector3              ((uint32_t)0x00000008) /* Write protection of Sector  */
#define OB_WRP_Sector4              ((uint32_t)0x00000010) /* Write protection of Sector  */
#define OB_WRP_Sector5              ((uint32_t)0x00000020) /* Write protection of Sector  */
#define OB_WRP_Sector6              ((uint32_t)0x00000040) /* Write protection of Sector  */
#define OB_WRP_Sector7              ((uint32_t)0x00000080) /* Write protection of Sector  */
#define OB_WRP_Sector8              ((uint32_t)0x00000100) /* Write protection of Sector  */
#define OB_WRP_Sector9              ((uint32_t)0x00000200) /* Write protection of Sector  */
#define OB_WRP_Sector10             ((uint32_t)0x00000400) /* Write protection of Sector  */
#define OB_WRP_Sector11             ((uint32_t)0x00000800) /* Write protection of Sector  */
#define OB_WRP_Sector12             ((uint32_t)0x00001000) /* Write protection of Sector  */
#define OB_WRP_Sector13             ((uint32_t)0x00002000) /* Write protection of Sector  */
#define OB_WRP_Sector14             ((uint32_t)0x00004000) /* Write protection of Sector  */
#define OB_WRP_Sector15             ((uint32_t)0x00008000) /* Write protection of Sector  */

#define OB_WRP_Sector16             ((uint32_t)0x00010000) /* Write protection of Sector*/
#define OB_WRP_Sector17             ((uint32_t)0x00020000) /* Write protection of Sector*/
#define OB_WRP_Sector18             ((uint32_t)0x00040000) /* Write protection of Sector */
#define OB_WRP_Sector19             ((uint32_t)0x00080000) /* Write protection of Sector */
#define OB_WRP_Sector20             ((uint32_t)0x00100000) /* Write protection of Sector */
#define OB_WRP_Sector21             ((uint32_t)0x00200000) /* Write protection of Sector */
#define OB_WRP_Sector22             ((uint32_t)0x00400000) /* Write protection of Sector */
#define OB_WRP_Sector23             ((uint32_t)0x00800000) /* Write protection of Sector */
#define OB_WRP_Sector24             ((uint32_t)0x01000000) /* Write protection of Sector */
#define OB_WRP_Sector25             ((uint32_t)0x02000000) /* Write protection of Sector */
#define OB_WRP_Sector26             ((uint32_t)0x04000000) /* Write protection of Sector */
#define OB_WRP_Sector27             ((uint32_t)0x08000000) /* Write protection of Sector */
#define OB_WRP_Sector28             ((uint32_t)0x10000000) /* Write protection of Sector */
#define OB_WRP_Sector29             ((uint32_t)0x20000000) /* Write protection of Sector */
#define OB_WRP_Sector30             ((uint32_t)0x40000000) /* Write protection of Sector */
#define OB_WRP_Sector31               /* Write protection of Sector */

#define OB_WRP_AllSector             ((uint32_t)0xFFFFFFFF) /*!< Write protection of all Sectors */

#define IS_OB_WRP(SECTOR) (((SECTOR) != 0x0000000))

#define IS_OB_WRP(SECTOR) (((SECTOR) != 0x0000000))

/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_Read_Protection FLASH_Option_Bytes_Read_Protection
  * @{
  */

/**
  * @brief  FLASH_Read_Protection_Level  FLASH_Read_Protection_Level
  */
#define OB_RDP_Level_0   ((uint16_t)0x55AA)
#define OB_RDP_Level_1   ((uint16_t)0x44BB)
#define OB_RDP_Level_2   ((uint16_t)0x33CC) /* Warning: When enabling read protection level 2 
                                                it's no more possible to go back to level 1 or 0 */

#define IS_OB_RDP(LEVEL) (((LEVEL) == OB_RDP_Level_0)||\
                          ((LEVEL) == OB_RDP_Level_1)||\
                          ((LEVEL) == OB_RDP_Level_2))
/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_IWatchdog FLASH_Option_Bytes_IWatchdog
  * @{
  */

#define OB_IWDG_SW                     ((uint8_t)0x01)  /*!< Software IWDG selected */
#define OB_IWDG_HW                     ((uint8_t)0x00)  /*!< Hardware IWDG selected */
#define IS_OB_IWDG_SOURCE(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW))

/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_nRST_STOP FLASH_Option_Bytes_nRST_STOP
  * @{
  */

#define OB_STOP_NoRST                  ((uint8_t)0x02) /*!< No reset generated when entering in STOP */
#define OB_STOP_RST                    ((uint8_t)0x00) /*!< Reset generated when entering in STOP */
#define IS_OB_STOP_SOURCE(SOURCE) (((SOURCE) == OB_STOP_NoRST) || ((SOURCE) == OB_STOP_RST))

/**
  * @}
  */


/** @defgroup FLASH_Option_Bytes_BOOT1 FLASH_Option_Bytes_BOOT1
  * @{
  */

#define OB_BOOT1_RESET                 ((uint8_t)0x00) /*!< BOOT1 Reset */
#define OB_BOOT1_SET                   ((uint8_t)0x10) /*!< BOOT1 Set */
#define IS_OB_BOOT1(BOOT1) (((BOOT1) == OB_BOOT1_RESET) || ((BOOT1) == OB_BOOT1_SET))

/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_BOOT0 FLASH_Option_Bytes_BOOT0
  * @{
  */

#define OB_BOOT0_RESET                 ((uint8_t)0x00) /*!< BOOT0 Reset */
#define OB_BOOT0_SET                   ((uint8_t)0x08) /*!< BOOT0 Set */
#define IS_OB_BOOT0(BOOT0) (((BOOT0) == OB_BOOT0_RESET) || ((BOOT0) == OB_BOOT0_SET))

/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_BOOT0SW FLASH_Option_Bytes_BOOT0SW
  * @{
  */

#define OB_BOOT0_SW                   ((uint8_t)0x00) /*!< BOOT0 pin disabled */
#define OB_BOOT0_HW                   ((uint8_t)0x80) /*!< BOOT0 pin bonded with GPIO */
#define IS_OB_BOOT0SW(BOOT0) (((BOOT0) == OB_BOOT0_SW) || ((BOOT0) == OB_BOOT0_HW))

/**
  * @}
  */


/** @defgroup FLASH_Flags FLASH_Flags
  * @{
  */

#define FLASH_FLAG_BSY                 FLASH_SR_BSY     /*!< FLASH Busy flag */
#define FLASH_FLAG_PGERR               FLASH_SR_PGERR   /*!< FLASH Programming error flag */
#define FLASH_FLAG_WRPERR              FLASH_SR_WRPRTERR  /*!< FLASH Write protected error flag */
#define FLASH_FLAG_EOP                 FLASH_SR_EOP     /*!< FLASH End of Programming flag */

#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFFFFCB) == 0x00000000) && ((FLAG) != 0x00000000))

#define IS_FLASH_GET_FLAG(FLAG)  (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_PGERR) || \
                                  ((FLAG) == FLASH_FLAG_WRPERR) || ((FLAG) == FLASH_FLAG_EOP))
/**
  * @}
  */

/** @defgroup FLASH_Timeout_definition FLASH_Timeout_definition
  * @{
  */
#define FLASH_ER_PRG_TIMEOUT         ((uint32_t)0x000B0000)

/**
  * @}
  */


/** @defgroup FLASH_WRProt FLASH_WRProt
  * @{
  */
#define FLASH_WRProt_Pages0to3         OB_WRP_Pages0to3
#define FLASH_WRProt_Pages4to7         OB_WRP_Pages4to7
#define FLASH_WRProt_Pages8to11        OB_WRP_Pages8to11
#define FLASH_WRProt_Pages12to15       OB_WRP_Pages12to15
#define FLASH_WRProt_Pages16to19       OB_WRP_Pages16to19
#define FLASH_WRProt_Pages20to23       OB_WRP_Pages20to23
#define FLASH_WRProt_Pages24to27       OB_WRP_Pages24to27
#define FLASH_WRProt_Pages28to31       OB_WRP_Pages28to31
#define FLASH_WRProt_Pages32to35       OB_WRP_Pages32to35
#define FLASH_WRProt_Pages36to39       OB_WRP_Pages36to39
#define FLASH_WRProt_Pages40to43       OB_WRP_Pages40to21
#define FLASH_WRProt_Pages44to47       OB_WRP_Pages44to23
#define FLASH_WRProt_Pages48to51       OB_WRP_Pages48to51
#define FLASH_WRProt_Pages52to55       OB_WRP_Pages52to55
#define FLASH_WRProt_Pages56to59       OB_WRP_Pages56to59
#define FLASH_WRProt_Pages60to63       OB_WRP_Pages60to63


#define FLASH_WRProt_AllPages          OB_WRP_AllPages
/**
  * @}
  */

/** @defgroup FLASH_Legacy FLASH_Legacy
  * @{
  */
#define FLASH_EraseOptionBytes               FLASH_OB_Erase
#define FLASH_EnableWriteProtection          FLASH_OB_EnableWRP
#define FLASH_UserOptionByteConfig           FLASH_OB_UserConfig
#define FLASH_ProgramOptionByteData          FLASH_OB_ProgramData
#define FLASH_GetUserOptionByte              FLASH_OB_GetUser
#define FLASH_GetWriteProtectionOptionByte   FLASH_OB_GetWRP

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */


/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */


/* FLASH Interface configuration functions ************************************/
void FLASH_SetLatency(uint32_t FLASH_Latency);
void FLASH_PrefetchBufferCmd(FunctionalState NewState);
FlagStatus FLASH_GetPrefetchBufferStatus(void);

/* FLASH Memory Programming functions *****************************************/
void FLASH_Unlock(void);
void FLASH_Lock(void);

FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
FLASH_Status FLASH_EraseAllPages(void);
FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);

/* FLASH Option Bytes Programming functions *****************************************/
void FLASH_OBUnlock(void);
void FLASH_OBLock(void);
void FLASH_OBLaunch(void);
FLASH_Status FLASH_OBErase(void);
FLASH_Status FLASH_OBEnableWRP(uint32_t OB_WRP);
FLASH_Status FLASH_OBRDPConfig(uint16_t OB_RDP);
FLASH_Status FLASH_OBUserConfig(uint8_t OB_IWDG, uint8_t OB_STOP);
FLASH_Status FLASH_OBBOOTConfig(uint8_t OB_BOOT1);
FLASH_Status FLASH_OBBOOT0Config(uint8_t OB_BOOT0);
FLASH_Status FLASH_OBBOOT0SWConfig(uint8_t OB_BOOT0SW);
FLASH_Status FLASH_OBWriteUser(uint8_t OB_USER);
FLASH_Status FLASH_OBProgramData(uint32_t Address, uint32_t Data);
uint8_t FLASH_OBGetUser(void);
uint32_t FLASH_OBGetWRP(void);
FlagStatus FLASH_OBGetRDP(void);

/* FLASH Interrupts and flags management functions **********************************/
void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
void FLASH_ClearFlag(uint32_t FLASH_FLAG);
FLASH_Status FLASH_GetStatus(void);
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);

void FLASH_GetDevice96BitUID(uint32_t *UID);

#ifdef __cplusplus
}
#endif

#endif /*__HK32C030XX_FLASH_H */



